using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using Microsoft.Data.Extensions;
using Devart.Data.PostgreSql;

namespace MvcCms.Data.Code
{
    public class EntityCmsRepository : ICmsRepository
    {
        #region Constructors

        private readonly IEntityAccountRepository _account;
        private readonly MvcCmsEntities _entities;
        private readonly IEntitiesProvider _entitiesProvider;

        private EntityCmsRepository(IEntitiesProvider entitiesProvider)
        {
            _entities = entitiesProvider.GetEntityContext();
            _entitiesProvider = entitiesProvider;
        }

        public EntityCmsRepository(IEntitiesProvider entitiesProvider, IEntityAccountRepository account)
        {
            _entities = entitiesProvider.GetEntityContext();
            _entitiesProvider = entitiesProvider;
            _account = account;
        }


        #endregion

        #region Content Category methods

        public int CreateContentCategory(ContentCategory categoryToCreate)
        {
            categoryToCreate.Editor = _account.GetUser(categoryToCreate.Editor.UserID);
            int? parentCategoryId = null;
            if (categoryToCreate.ParentCategory != null)
            {
                parentCategoryId = categoryToCreate.ParentCategory.CategoryID;
            }

            var command = _entities.CreateStoreCommand("insert_content_category",
                CommandType.StoredProcedure,
                new PgSqlParameter("_AddedByID", categoryToCreate.Editor.UserID),
                new PgSqlParameter("_Title", categoryToCreate.Title),
                new PgSqlParameter("_Path", categoryToCreate.Path),
                new PgSqlParameter("_Importance", categoryToCreate.Importance),
                new PgSqlParameter("_Description", categoryToCreate.Description),
                new PgSqlParameter("_ShowInNav", categoryToCreate.ShowInNav),
                new PgSqlParameter("_OnlyForMembers", categoryToCreate.OnlyForMembers),
                new PgSqlParameter("_OnlyForPayingMembers", categoryToCreate.OnlyForPayingMembers),
                new PgSqlParameter("_RequiresSSL", categoryToCreate.RequireSSL),
                new PgSqlParameter("_SinglePath", categoryToCreate.SinglePath),
                new PgSqlParameter("_ParentList", categoryToCreate.ParentList),
                new PgSqlParameter("_UsesCustomAreaRoute", categoryToCreate.UsesCustomAreaRoute),
                new PgSqlParameter("_SubPageHeader", categoryToCreate.SubPageHeader),
                new PgSqlParameter("_PortalID", categoryToCreate.Portal.PortalID),
                new PgSqlParameter("_ExternalURL", categoryToCreate.ExternalURL),
                new PgSqlParameter("_NumberOfParents", categoryToCreate.NumberOfParents),
                new PgSqlParameter("_ParentCategoryID", parentCategoryId)
            );

            using (command.Connection.CreateConnectionScope())
            {
                using (var reader = command.ExecuteReader())
                {
                    reader.Read();
                    var categoryId = reader.GetValue(0);
                    var newCategoryId = int.Parse(categoryId.ToString());
                    var categoryToRefresh = GetContentCategory(newCategoryId);
                    _entitiesProvider.Refresh(_entities, RefreshMode.StoreWins, categoryToRefresh);
                    return newCategoryId;
                }
            }
        }

        public ContentCategory GetContentCategory(int id)
        {
            if (id == 0)
            {
                //this is needed for the set published version page
                return (from s in _entities.ContentCategorySet
                            .Include("ParentCategory")
                            .Include("SubCategories")
                            .Include("Portal")
                        where s.Title == "Home"
                        select s).FirstOrDefault();
            }
            return (from s in _entities.ContentCategorySet
                        .Include("ParentCategory")
                        .Include("SubCategories")
                        .Include("Portal")
                    where s.CategoryID == id
                    select s).FirstOrDefault();
        }

        public ContentCategory GetContentCategory(int id, string direction, bool isSubCategory, Portal portal)
        {
            var category = (from s in _entities.ContentCategorySet
                            where s.CategoryID == id &&
                                  s.Portal.PortalID == portal.PortalID
                            select s).FirstOrDefault();

            var importance = category.Importance;
            if (direction == "up")
            {
                importance = importance - 1;
            }
            else
            {
                importance = importance + 1;
            }
            if (!isSubCategory)
            {
                return (from s in _entities.ContentCategorySet
                        where s.Importance == importance
                              && s.Portal.PortalID == portal.PortalID
                        select s).FirstOrDefault();
            }
            return (from s in _entities.ContentCategorySet
                    where s.Importance == importance
                          && s.ParentCategory.CategoryID == category.ParentCategory.CategoryID
                          && s.Portal.PortalID == portal.PortalID
                    select s).FirstOrDefault();
        }

        public ContentCategory GetContentCategoryByPath(string path, Portal portal)
        {
            return (from s in _entities.ContentCategorySet
                    where s.SinglePath == path && s.Portal.PortalID == portal.PortalID
                    select s).FirstOrDefault();
        }

        public ContentCategory GetContentCategoryByFullPath(string path, Portal portal)
        {
            return (from s in _entities.ContentCategorySet
                    where s.Path == path && s.Portal.PortalID == portal.PortalID
                    select s).FirstOrDefault();
        }

        public IEnumerable<DTOSubCategory> ListSubCats(int categoryId)
        {
            return (from c in _entities.DTOSubCategorySet
                    where c.ParentCategoryID == categoryId
                    orderby c.Importance, c.Title
                    select c).ToList();
        }

        public IEnumerable<ContentCategory> ListCategories(Portal portal)
        {
            return (from c in _entities.ContentCategorySet.Include("SubCategories")
                    where c.Portal.PortalID == portal.PortalID
                    orderby c.ParentCategory.CategoryID, c.Importance, c.Title
                    select c).ToList();
        }

        public IEnumerable<ContentCategory> ListAllCategories()
        {
            return (from c in _entities.ContentCategorySet
                       .Include("ParentCategory")
                       .Include("SubCategories")
                       .Include("Portal")
                    orderby c.ParentCategory.CategoryID, c.Importance, c.Title
                    select c).ToList();
        }
        public IEnumerable<ContentCategory> ListAllCategoriesWithPages()
        {
            return (from c in _entities.ContentCategorySet
                       .Include("ParentCategory")
                       .Include("SubCategories")
                       .Include("Portal")
                       .Include("ContentPages")
                    orderby c.ParentCategory.CategoryID, c.Importance, c.Title
                    select c).ToList();
        }
        public IEnumerable<ContentCategory> ListCategoriesForBackOffice(Portal portal)
        {
            return (from c in _entities.ContentCategorySet
                    where c.Title != "Home" && c.Portal.PortalID == portal.PortalID
                    orderby c.Importance, c.Title
                    select c).ToList();
        }

        public ContentCategory EditContentCategory(ContentCategory categoryToEdit)
        {
            var originalCategory = GetContentCategory(categoryToEdit.CategoryID);

            // Save changes
            _entities.ContentCategorySet.ApplyCurrentValues(categoryToEdit);
            _entities.SaveChanges();
            return categoryToEdit;
        }

        public void DeleteContentCategory(ContentCategory categoryToDelete)
        {
            var command = _entities.CreateStoreCommand("delete_ContentCategory",
                 CommandType.StoredProcedure,
                 new PgSqlParameter("CategoryID", categoryToDelete.CategoryID)
                );
            using (command.Connection.CreateConnectionScope())
            {
                command.ExecuteReader();
                var cats = ListAllCategories();
                _entitiesProvider.Refresh(_entities, RefreshMode.StoreWins, cats);
            }
        }

        public void SetPublishedPage(int contentpageId)
        {
            //call sp to change page
            var command = _entities.CreateStoreCommand("setPublishedPage",
                         CommandType.StoredProcedure,
                         new PgSqlParameter("_ContentPageID", contentpageId));
            using (command.Connection.CreateConnectionScope())
            {
                command.ExecuteNonQuery();
            }
        }

        #endregion

        #region Content Page methods

        public ContentPage GetContentPage(int id)
        {
            return (from s in _entities.ContentPageSet
                         .Include("ContentCategory")
                         .Include("Contributor")
                    where s.ContentPageID == id
                    select s).FirstOrDefault();
        }

        private ContentPage GetContentPageFull(int id)
        {
            return (from s in _entities.ContentPageSet
                         .Include("ContentCategory")
                         .Include("Contributor")
                         .Include("Portal")
                         .Include("Editor")
                         .Include("Editor.Portal")
                         .Include("Contributor.Portal")
                         .Include("Contributor")
                    where s.ContentPageID == id
                    select s).FirstOrDefault();

        }

        public ContentPage GetContentPage(int id, string direction)
        {
            var page = (from s in _entities.ContentPageSet
                                    .Include("ContentCategory")
                        where s.ContentPageID == id
                        select s).FirstOrDefault();

            var importance = page.Importance.GetValueOrDefault();
            if (direction == "up")
            {
                importance = importance - 1;
            }
            else
            {
                importance = importance + 1;
            }

            return (from s in _entities.ContentPageSet
                        .Include("ContentCategory")
                    where s.Importance == importance &&
                          s.IsSubPage == true &&
                          s.ContentCategory.CategoryID == page.ContentCategory.CategoryID
                    select s).FirstOrDefault();
        }

        public DTOPage GetDTOContentPage(int id)
        {
            return (from s in _entities.DTOPageSet
                    where s.ContentPageID == id
                    select s).FirstOrDefault();
        }

        public ContentPage GetPublishedCatContentPageByCategory(int catId)
        {
            //instead of doing this here do it in the service with the cache
            return (from s in _entities.ContentPageSet.Include("ContentCategory")
                    where s.ContentCategory.CategoryID == catId &&
                          s.IsCategoryPage && s.IsSubPage == false
                    select s).FirstOrDefault();
        }

        public DTOPage GetCurrentPageForCategory(int catId)
        {
            return (from s in _entities.DTOPageSet
                    where s.CategoryID == catId && s.IsCategoryPage && s.IsSubPage == false
                    select s).FirstOrDefault();
        }
        public DTOPage GetAltLanguagePage(int languageId, int parentPageId)
        {
            return (from s in _entities.DTOPageSet
                    where s.LanguageID == languageId &&
                            s.AltLanguageForPageID == parentPageId
                    select s).FirstOrDefault();
        }
        public ContentPage GetAltLanguagePageForCMS(string languagePathId, int parentPageId)
        {
            var language = (from l in _entities.LanguageSet
                            where l.PathID == languagePathId
                            select l).FirstOrDefault();

            return (from s in _entities.ContentPageSet
                    .Include("ContentCategory")
                    where s.Language.LanguageID == language.LanguageID &&
                            s.ParentLanguageVersion.ContentPageID == parentPageId
                    select s).FirstOrDefault();
        }
        public IEnumerable<DTOContentPageForEditor> ListPages(int portalId)
        {
            return (from c in _entities.DTOContentPageForEditorSet
                    where c.PortalID == portalId
                    orderby c.CatName, c.Title
                    select c).ToList();
        }

        public IEnumerable<DTOPage> ListPagesForCategory(int catId)
        {
            return (from c in _entities.DTOPageSet
                    where c.CategoryID == catId && c.IsSubPage == true
                    orderby c.Importance, c.Title
                    select c).ToList();
        }

        public IEnumerable<DTOPage> ListUnpublishedPagesForCategory(int catId)
        {
            return (from c in _entities.DTOPageSet
                    where c.CategoryID == catId &&
                    c.IsSubPage == false &&
                    c.IsCategoryPage == false &&
                    c.AltLanguageForPageID == null
                    orderby c.Importance, c.Title
                    select c).ToList();
        }

        public IEnumerable<DTOContentPageForEditor> ListPages(Guid contributorId)
        {
            return (from c in _entities.DTOContentPageForEditorSet
                    where c.ContributorID == contributorId
                    orderby c.CatName, c.Title
                    select c).ToList();
        }

        public IEnumerable<ContentPage> ListSubPages()
        {
            return (from c in _entities.ContentPageSet.Include("ContentCategory")
                    where c.IsSubPage == true &&
                             c.Approved == true
                    orderby c.Importance, c.Title
                    select c).ToList();
        }
        public IEnumerable<ContentPage> ListAltLanguagePages()
        {
            return (from c in _entities.ContentPageSet
                       .Include("ParentLanguageVersion")
                       .Include("Language")
                    where c.ParentLanguageVersion.ContentPageID != null
                    orderby c.Importance, c.Title
                    select c).ToList();
        }
        public IEnumerable<DTOContentComment> ListContentCommentReplies(int commentId)
        {
            return (from c in _entities.DTOContentCommentSet
                    where c.ParentCommentID == commentId
                    orderby c.AddedDate descending
                    select c).ToList();
        }

        public IEnumerable<DTOContentComment> ListContentComments(int pageId)
        {
            return (from c in _entities.DTOContentCommentSet
                    where c.ContentPageID == pageId && c.ParentCommentID == null
                    select c).ToList();
        }
        public IEnumerable<ContentComment> ListContentComments(Guid userId)
        {
            return (from c in _entities.ContentCommentSet
                    .Include("ContentPage")
                    .Include("ContentPage.ContentCategory")
                    where c.User.UserID == userId
                    orderby c.AddedDate descending
                    select c).Take(10).ToList();
        }
        public ContentComment GetContentComment(int id)
        {
            return (from s in _entities.ContentCommentSet.Include("User").Include("ContentPage")
                    where s.CommentID == id
                    select s).FirstOrDefault();
        }

        public IEnumerable<ContentPage> ListPagesByCat(int catId, Portal currentportal)
        {
            return (from c in _entities.ContentPageSet.Include("ContentCategory")
                    where c.ContentCategory.CategoryID == catId
                    orderby c.ContentCategory.Title, c.Title
                    select c).ToList();
        }

        public IEnumerable<ContentPage> ListCategoryPagesByCategory(int catId, Portal currentportal)
        {
            return (from c in _entities.ContentPageSet.Include("ContentCategory")
                    where c.ContentCategory.CategoryID == catId && c.IsSubPage == false
                    orderby c.ContentCategory.Title, c.Title
                    select c).ToList();
        }

        public ContentPage EditContentPage(ContentPage pageToEdit)
        {
            if (pageToEdit.Contributor == null)
            {
                pageToEdit.Contributor = pageToEdit.Editor;
            }
            var command = _entities.CreateStoreCommand("update_ContentPage",
                     CommandType.StoredProcedure,
                     new PgSqlParameter("_ContentPageID", pageToEdit.ContentPageID),
                     new PgSqlParameter("_ContributorID", pageToEdit.Contributor.UserID),
                     new PgSqlParameter("_CategoryID", pageToEdit.ContentCategory.CategoryID),
                     new PgSqlParameter("_Title", pageToEdit.Title),
                     new PgSqlParameter("_Path", pageToEdit.Path),
                     new PgSqlParameter("_Summary", pageToEdit.Summary),
                     new PgSqlParameter("_Body", pageToEdit.Body),
                     new PgSqlParameter("_ReleaseDate", pageToEdit.ReleaseDate),
                     new PgSqlParameter("_ExpireDate", pageToEdit.ExpireDate),
                     new PgSqlParameter("_Approved", pageToEdit.Approved),
                     new PgSqlParameter("_Listed", pageToEdit.Listed),
                     new PgSqlParameter("_CommentsEnabled", pageToEdit.CommentsEnabled),
                     new PgSqlParameter("_OnlyForMembers", pageToEdit.OnlyForMembers),
                     new PgSqlParameter("_ViewCount", pageToEdit.ViewCount),
                     new PgSqlParameter("_Votes", pageToEdit.Votes),
                     new PgSqlParameter("_TotalRating", pageToEdit.TotalRating),
                     new PgSqlParameter("_IsCategoryPage", pageToEdit.IsCategoryPage),
                     new PgSqlParameter("_IsSubPage", pageToEdit.IsSubPage),
                     new PgSqlParameter("_AnonCommentsEnabled", pageToEdit.AnonCommentsEnabled),
                     new PgSqlParameter("_UseWikiMarkup", pageToEdit.UseWikiMarkup),
                     new PgSqlParameter("_Description", pageToEdit.Description),
                     new PgSqlParameter("_ShowContributorLink", pageToEdit.ShowContributorLink),
                     new PgSqlParameter("_Importance", pageToEdit.Importance)
                );

            using (command.Connection.CreateConnectionScope())
            {
                command.ExecuteReader();
                return pageToEdit;
            }
        }

        public ContentComment EditContentComment(ContentComment contentcommentToEdit)
        {
            // Save changes
            _entities.ContentCommentSet.ApplyCurrentValues(contentcommentToEdit);
            _entities.SaveChanges();
            return contentcommentToEdit;
        }

        public void DeleteContentPage(ContentPage pageToDelete)
        {
            var command = _entities.CreateStoreCommand("delete_ContentPage",
                 CommandType.StoredProcedure,
                 new PgSqlParameter("_ContentPageID", pageToDelete.ContentPageID)
                );
            using (command.Connection.CreateConnectionScope())
            {
                command.ExecuteReader();
                _entities.Detach(pageToDelete);
            }

        }

        public void DeleteContentComment(ContentComment commentToDelete)
        {
            var originalComment = (from s in _entities.ContentCommentSet.Include("Replies")
                                   where s.CommentID == commentToDelete.CommentID
                                   select s).FirstOrDefault();

            _entities.DeleteObject(originalComment);
            _entities.SaveChanges();
        }

        public ContentComment CreateContentComment(ContentComment contentcommentToCreate)
        {
            _entities.ContentCommentSet.AddObject(contentcommentToCreate);
            _entities.SaveChanges();
            return contentcommentToCreate;
        }

        public int CreateContentPage(ContentPage contentpageToCreate)
        {
            if (contentpageToCreate.Contributor == null)
            {
                contentpageToCreate.Contributor = contentpageToCreate.Editor;
            }
            ContentPage parentLanguageVersion;
            var altLanguageParentPageId = 0;
            if (contentpageToCreate.ParentLanguageVersion != null)
            {
                parentLanguageVersion = GetContentPage(contentpageToCreate.ParentLanguageVersion.ContentPageID);
                altLanguageParentPageId = parentLanguageVersion.ContentPageID;
            }
            var command = _entities.CreateStoreCommand("insert_content_page",
                 CommandType.StoredProcedure,
                 new PgSqlParameter("_ContributorID", contentpageToCreate.Contributor.UserID),
                 new PgSqlParameter("_AddedByID", contentpageToCreate.Editor.UserID),
                 new PgSqlParameter("_CategoryID", contentpageToCreate.ContentCategory.CategoryID),
                 new PgSqlParameter("_Title", contentpageToCreate.Title),
                 new PgSqlParameter("_Path", contentpageToCreate.Path),
                 new PgSqlParameter("_Summary", contentpageToCreate.Summary),
                 new PgSqlParameter("_Body", contentpageToCreate.Body),
                 new PgSqlParameter("_ReleaseDate", contentpageToCreate.ReleaseDate),
                 new PgSqlParameter("_ExpireDate", contentpageToCreate.ExpireDate),
                 new PgSqlParameter("_Approved", contentpageToCreate.Approved),
                 new PgSqlParameter("_Listed", contentpageToCreate.Listed),
                 new PgSqlParameter("_CommentsEnabled", contentpageToCreate.CommentsEnabled),
                 new PgSqlParameter("_OnlyForMembers", contentpageToCreate.OnlyForMembers),
                 new PgSqlParameter("_ViewCount", contentpageToCreate.ViewCount),
                 new PgSqlParameter("_Votes", contentpageToCreate.Votes),
                 new PgSqlParameter("_TotalRating", contentpageToCreate.TotalRating),
                 new PgSqlParameter("_IsCategoryPage", contentpageToCreate.IsCategoryPage),
                 new PgSqlParameter("_IsSubPage", contentpageToCreate.IsSubPage),
                 new PgSqlParameter("_AnonCommentsEnabled", contentpageToCreate.AnonCommentsEnabled),
                 new PgSqlParameter("_UseWikiMarkup", contentpageToCreate.UseWikiMarkup),
                 new PgSqlParameter("_Importance", contentpageToCreate.Importance),
                 new PgSqlParameter("_Description", contentpageToCreate.Description),
                 new PgSqlParameter("_PortalID", contentpageToCreate.Portal.PortalID),
                 new PgSqlParameter("_LanguageID", contentpageToCreate.Language.LanguageID),
                 new PgSqlParameter("_ShowContributorLink", contentpageToCreate.ShowContributorLink),
                 new PgSqlParameter("_AltLanguageForPageID", altLanguageParentPageId != 0 ? (object)altLanguageParentPageId : DBNull.Value)
                );

            using (command.Connection.CreateConnectionScope())
            {
                using (var reader = command.ExecuteReader())
                {
                    reader.Read();
                    var pageId = reader.GetValue(0);
                    var newPageId = int.Parse(pageId.ToString());
                    var newPage = GetContentPageFull(newPageId);
                    contentpageToCreate = newPage;
                    return newPageId;
                }
            }
        }

        #endregion

        #region Module methods

        public Module GetModule(int moduleId)
        {
            return (from s in _entities.ModuleSet
                        .Include("ContentCategory")
                        .Include("ContentPage")
                        .Include("WeightedContentsSettings.AllowedRoles")
                    where s.ModuleID == moduleId
                    select s).FirstOrDefault();
        }
        public Widget GetWidget(int widgetId)
        {
            return (from s in _entities.WidgetSet
                        .Include("Category")
                        .Include("Page")
                        .Include("WeightedContentsSettings.AllowedRoles")
                    where s.WidgetID == widgetId
                    select s).FirstOrDefault();
        }
        public WeightedContent GetWeightedContent(int weightedContentId)
        {
            return (from s in _entities.WeightedContentSet
                    where s.WeightedContentID == weightedContentId
                    select s).FirstOrDefault();
        }
        public Module CreateModule(Module moduleToCreate)
        {
            _entities.ModuleSet.AddObject(moduleToCreate);
            _entities.SaveChanges();
            return moduleToCreate;
        }
        public Widget CreateWidget(Widget widgetToCreate)
        {
            _entities.WidgetSet.AddObject(widgetToCreate);
            _entities.SaveChanges();
            return widgetToCreate;
        }
        public WeightedContent CreateWeightedContent(WeightedContent weightedContentToCreate)
        {
            _entities.WeightedContentSet.AddObject(weightedContentToCreate);
            _entities.SaveChanges();
            return weightedContentToCreate;
        }
        public IEnumerable<Module> ListModules(Portal currentPortal)
        {
            return (from c in _entities.ModuleSet
                    where c.Portal.PortalID == currentPortal.PortalID
                    orderby c.Title
                    select c).ToList();
        }
        public IEnumerable<WeightedContentModule> ListWeightedContentModulesForCache()
        {
            var query = (from c in _entities.WeightedContentModuleSet select c).AsQueryable();

            query = query.Include(wcm => wcm.WeightedContent);
            query = query.Include(wcm => wcm.AllowedRoles);
            query = query.Include(wcm => wcm.Module);

            return query.ToList();
        }
        public IEnumerable<WeightedContentWidget> ListWeightedContentWidgetsForCache()
        {
            var query = (from c in _entities.WeightedContentWidgetSet select c).AsQueryable();

            query = query.Include(wcm => wcm.WeightedContent);
            query = query.Include(wcm => wcm.AllowedRoles);
            query = query.Include(wcm => wcm.Widget);

            return query.ToList();
        }
        public IEnumerable<DTOModule> ListModulesForPage(int pageId, Portal currentPortal)
        {
            var page = GetContentPage(pageId);

            return (from c in _entities.DTOModuleSet
                    where
                        c.Active && c.IsForWeightedContent.Equals(false) &&
                        (c.AllPages || c.ContentCategoryID == page.ContentCategory.CategoryID ||
                         c.ContentPageID == page.ContentPageID) &&
                         c.PortalID == currentPortal.PortalID
                    orderby c.Title
                    select c).ToList();
        }
        public IEnumerable<Widget> ListWidgets(Portal currentPortal)
        {
            return (from c in _entities.WidgetSet
                    where c.Portal.PortalID == currentPortal.PortalID
                    orderby c.Title
                    select c).ToList();
        }
        public IEnumerable<Widget> ListWidgetsForPage(int pageId, Portal currentPortal)
        {
            var page = GetContentPage(pageId);

            return (from c in _entities.WidgetSet
                    where
                        c.Active &&
                        (c.AllPages || c.ContentCategoryID == page.ContentCategory.CategoryID ||
                         c.ContentPageID == page.ContentPageID) && string.IsNullOrEmpty(c.ZoneName) &&
                         c.PortalID == currentPortal.PortalID
                    orderby c.Title
                    select c).ToList();
        }
        public IEnumerable<Widget> ListWidgetsForZones(Portal currentPortal)
        {
            return (from c in _entities.WidgetSet
                    where
                        c.Active &&
                        c.ZoneName != null &&
                         c.PortalID == currentPortal.PortalID
                    orderby c.Title
                    select c).ToList();
        }
        public IEnumerable<WeightedContent> ListWeightedContents(Portal currentPortal)
        {
            return (from c in _entities.WeightedContentSet
                    where c.Portal.PortalID == currentPortal.PortalID &&
                    c.Active
                    select c).ToList();
        }
        public IEnumerable<WeightedContentModule> ListWeightedContentModules(Portal currentPortal)
        {
            return (from c in _entities.WeightedContentModuleSet
                    where c.WeightedContent.Active
                    select c).ToList();
        }
        public void DeleteModule(int moduleId)
        {
            var originalModule = (from s in _entities.ModuleSet
                                  where s.ModuleID == moduleId
                                  select s).FirstOrDefault();

            _entities.DeleteObject(originalModule);
            _entities.SaveChanges();
        }
        public void DeleteWidget(int widgetId)
        {
            var originalWidget = (from s in _entities.WidgetSet
                                  where s.WidgetID == widgetId
                                  select s).FirstOrDefault();

            _entities.DeleteObject(originalWidget);
            _entities.SaveChanges();
        }
        public void DeleteWeightedContent(int weightedContentId)
        {
            var originalWeightedContent = GetWeightedContent(weightedContentId);

            _entities.DeleteObject(originalWeightedContent);
            _entities.SaveChanges();
        }
        public Module EditModule(Module moduleToEdit)
        {
            // Save changes
            _entities.ModuleSet.ApplyCurrentValues(moduleToEdit);
            _entities.SaveChanges();
            return moduleToEdit;
        }
        public Widget EditWidget(Widget widgetToEdit)
        {
            // Save changes
            _entities.WidgetSet.ApplyCurrentValues(widgetToEdit);
            _entities.SaveChanges();
            return widgetToEdit;
        }
        public WeightedContent EditWeightedContent(WeightedContent weightedContentoEdit)
        {
            // Save changes
            _entities.WeightedContentSet.ApplyCurrentValues(weightedContentoEdit);
            _entities.SaveChanges();
            return weightedContentoEdit;
        }
        #endregion

        public IEnumerable<Redirect> ListRedirects(int portalId)
        {
            return (from c in _entities.RedirectSet
                    where c.Portal.PortalID == portalId
                    orderby c.AddedDate
                    select c).ToList();
        }
        public Redirect GetRedirect(string path, Portal portal)
        {
            return (from s in _entities.RedirectSet
                    where s.OldPage == path &&
                    s.Portal.PortalID == portal.PortalID
                    select s).FirstOrDefault();
        }
        public Redirect GetGlobalRedirect(string path)
        {
            return (from s in _entities.RedirectSet
                    where s.OldPage == path
                    select s).FirstOrDefault();
        }
        public Redirect EditRedirect(Redirect redirectToEdit)
        {
            // Save changes
            _entities.RedirectSet.ApplyCurrentValues(redirectToEdit);
            _entities.SaveChanges();
            return redirectToEdit;
        }

        public Redirect CreateRedirect(Redirect redirectToCreate)
        {
            _entities.RedirectSet.AddObject(redirectToCreate);
            _entities.SaveChanges();
            return redirectToCreate;
        }
    }
}